use task::ThreadPool;
use std::fs;
use std::io::prelude::*;
use std::net::TcpListener;
use std::net::TcpStream;
use std::thread;
use std::time::Duration;

// http://127.0.0.1:7878/sleep
fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    let pool = ThreadPool::new(4);

    for stream in listener.incoming().take(2) {
        let stream = stream.unwrap();

        // thread::spawn：该函数创建一个新的执行线程。它接受一个|| 闭包作为参数，这是新线程将执行的代码。
        pool.execute(|| {
            handle_connection(stream);
        });
    }

    println!("Shutting down.");
}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 1024];
    stream.read(&mut buffer).unwrap();
    // 这个语句的作用是将 request_line 变量表示的 HTTP 请求第一行拆分为 status_line 和 filename 两个变量。
    // status_line 变量将保存 HTTP 状态码，filename 变量将保存文件名。
    // (status_line,filename) = match &request_line[..]
    let get = b"GET / HTTP/1.1\r\n";
    let sleep = b"GET /sleep HTTP/1.1\r\n";

    let (status_line, filename) = if buffer.starts_with(get) {
        ("HTTP/1.1 200 OK", "sill.html")
    } else if buffer.starts_with(sleep) {
        thread::sleep(Duration::from_secs(5));
        ("HTTP/1.1 200 OK", "sill.html")
    } else {
        ("HTTP/1.1 404 NOT FOUND", "404.html")
    };

    let contents = fs::read_to_string(filename).unwrap();

    let response = format!(
        "{}\r\nContent-Length: {}\r\n\r\n{}",
        status_line,
        contents.len(),
        contents
    );

    stream.write_all(response.as_bytes()).unwrap();
    stream.flush().unwrap();
}

/*
match 语句用于匹配一个值与一个模式。
在本例中，match 语句的模式是 &request_line[..]，该模式表示 request_line 变量表示的字符串的所有字符。

match 语句的返回值是一个 Result 类型的值。Result 类型是 Rust 中用于表示可能成功或失败的操作的类型。Result 类型的值可以是 Ok()（表示成功）或 Err()（表示失败）。

在 Rust 中，[...] 表示切片。切片是指向一个数组或字符串的子序列的指针。

request_line[..] 表示 request_line 变量表示的字符串的所有字符。
因此，match 语句的模式 &request_line[..] 表示 request_line 变量表示的字符串的所有字符。

*/